﻿// HwPs_Regist.cpp: 实现文件
//

#include "pch.h"
#include "LiWi.h"
#include "afxdialogex.h"
#include "HwPs_Regist.h"
#include <thread>
#include <chrono>
#include "liwishell.h"
#include "Data.h"
#include <future>

#define WM_UPDATE_LISTCTRL (WM_USER + 1)


// HwPs_Regist 对话框

IMPLEMENT_DYNAMIC(HwPs_Regist, CDialogEx)
HwPs_Regist::HwPs_Regist(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_HwPs_Regist, pParent)
{
}

HwPs_Regist::~HwPs_Regist()
{
	PMC_HwTimer(Data::handle, 0, 0, 0, 0, 0, 0);
}

void HwPs_Regist::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_CompareList, m_CompareList);
	DDX_Control(pDX, IDC_EncoderList, m_LatchedList);
}

struct  UpdateListCtrlData
{
	CString str;
	CString strPoint;
};

BEGIN_MESSAGE_MAP(HwPs_Regist, CDialogEx)
	ON_BN_CLICKED(IDC_Add, &HwPs_Regist::OnBnClickedAdd)
	ON_BN_CLICKED(IDC_Open, &HwPs_Regist::OnBnClickedOpen)
	ON_MESSAGE(WM_UPDATE_LISTCTRL,&HwPs_Regist::OnUpdateListCtrl)
	ON_BN_CLICKED(IDC_OpenCompare, &HwPs_Regist::OnBnClickedOpencompare)
	ON_BN_CLICKED(IDC_StartHwPs, &HwPs_Regist::OnBnClickedStarthwps)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_Delect, &HwPs_Regist::OnBnClickedDelect)
END_MESSAGE_MAP()


// HwPs_Regist 消息处理程序
//主窗口更新控件
LRESULT HwPs_Regist::OnUpdateListCtrl(WPARAM wParam, LPARAM lParam)
{
	//从iParam获取数据
	UpdateListCtrlData* pData = reinterpret_cast<UpdateListCtrlData*>(wParam);
	if (pData)
	{
		//更新控件
		int nIndex = m_LatchedList.InsertItem(m_LatchedList.GetItemCount(), pData->str);
		m_LatchedList.SetItemText(nIndex, 0, pData->str);
		m_LatchedList.SetItemText(nIndex, 1, pData->strPoint);
		//delete pData;
	}
	return 0;
}




BOOL HwPs_Regist::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// TODO:  在此添加额外的初始化

	CRect rect;
	//位置点位表
	m_CompareList.GetClientRect(&rect);
	m_CompareList.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
	m_CompareList.InsertColumn(0, _T("序号"), LVCFMT_LEFT, rect.Width() / 4);
	m_CompareList.InsertColumn(1, _T("点位"), LVCFMT_LEFT, rect.Width() * 3 / 4);
	//锁存表
	m_LatchedList.GetClientRect(&rect);
	m_LatchedList.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
	m_LatchedList.InsertColumn(0, _T("序号"), LVCFMT_LEFT, rect.Width() / 4);
	m_LatchedList.InsertColumn(1, _T("点位"), LVCFMT_LEFT, rect.Width() * 3 / 4);
	//((CListCtrl*)GetDlgItem(IDC_CompareAxis))->GetClientRect(&rect);
	//((CListCtrl*)GetDlgItem(IDC_CompareAxis))->InsertColumn(0, _T("序号"), LVCFMT_LEFT, rect.Width() / 4);
	//((CListCtrl*)GetDlgItem(IDC_CompareAxis))->InsertColumn(1, _T("点位"), LVCFMT_LEFT, rect.Width() * 3 / 4);

	//默认值
	GetDlgItem(IDC_AddPoint)->SetWindowTextW(_T("0"));
	((CButton*)GetDlgItem(IDC_CHECK1))->SetCheck(true);
	CString value;
	for (int i = 0; i < 4; i++)
	{
		value.Format(_T("%d"), i);
		((CComboBox*)GetDlgItem(IDC_CompareAxis))->AddString(value);
		((CComboBox*)GetDlgItem(IDC_EnocderAxis))->AddString(value);
	}
	for (int i = 0; i < 20; i++)
	{
		value.Format(_T("%d"), i);
		((CComboBox*)GetDlgItem(IDC_Out))->AddString(value);
	}	
	((CComboBox*)GetDlgItem(IDC_StartState))->AddString(_T("打开"));
	((CComboBox*)GetDlgItem(IDC_StartState))->AddString(_T("关闭"));
	((CComboBox*)GetDlgItem(IDC_Dir))->AddString(_T("不判断方向"));
	((CComboBox*)GetDlgItem(IDC_Dir))->AddString(_T("正方向"));
	((CComboBox*)GetDlgItem(IDC_Dir))->AddString(_T("反方向"));

	((CComboBox*)GetDlgItem(IDC_Mode))->AddString(_T("R0上升沿"));
	((CComboBox*)GetDlgItem(IDC_Mode))->AddString(_T("R0下降沿"));
	((CComboBox*)GetDlgItem(IDC_Mode))->AddString(_T("R1上升沿"));
	((CComboBox*)GetDlgItem(IDC_Mode))->AddString(_T("R1下降沿"));

	((CComboBox*)GetDlgItem(IDC_CompareAxis))->SetCurSel(0);
	((CComboBox*)GetDlgItem(IDC_EnocderAxis))->SetCurSel(0);
	((CComboBox*)GetDlgItem(IDC_Out))->SetCurSel(0);
	((CComboBox*)GetDlgItem(IDC_StartState))->SetCurSel(0);
	((CComboBox*)GetDlgItem(IDC_Dir))->SetCurSel(0);
	GetDlgItem(IDC_TimeCyc)->SetWindowTextW(_T("0"));
	GetDlgItem(IDC_TimeHave)->SetWindowTextW(_T("0"));
	GetDlgItem(IDC_DoNum)->SetWindowTextW(_T("0"));
	GetDlgItem(IDC_OUTState)->EnableWindow(false);
	((CComboBox*)GetDlgItem(IDC_Mode))->SetCurSel(0);

	GetDlgItem(IDC_StartPoint)->SetWindowTextW(_T("0"));
	GetDlgItem(IDC_EndPoint)->SetWindowTextW(_T("1000"));

	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常: OCX 属性页应返回 FALSE
}

/// <summary>
/// 新增点位
/// </summary>
void HwPs_Regist::OnBnClickedAdd()
{
	// TODO: 在此添加控件通知处理程序代码
	CString str, point;
	GetDlgItem(IDC_AddPoint)->GetWindowTextW(point);
	if (point != "")
	{

		str.Format(_T("%d"), m_CompareList.GetItemCount());
		int nIndex = m_CompareList.InsertItem(m_CompareList.GetItemCount(), str);
		m_CompareList.SetItemText(nIndex, 0, str);
		m_CompareList.SetItemText(nIndex, 1, point);
		return;
	}
	MessageBox(_T("请输入有效数字"));
}

/// <summary>
/// 锁存
/// </summary>
void HwPs_Regist::OnBnClickedOpen()
{
	// TODO: 在此添加控件通知处理程序代码
	if (!LatchedFlag)
	{
		LatchedFlag = true;
		m_LatchedList.DeleteAllItems();
		GetDlgItem(IDC_Open)->SetWindowTextW(_T("关闭"));
		GetDlgItem(IDC_EnocderAxis)->EnableWindow(false);
		GetDlgItem(IDC_Mode)->EnableWindow(false);
		select = ((CComboBox*)GetDlgItem(IDC_Mode))->GetCurSel();
		GetDlgItem(IDC_EnocderAxis)->GetWindowTextW(enocderAxis);
		std::thread([this]() {
			int mode = 0;
			int Num = 1;
			switch (select)
			{
			case 0:	mode = 3; break;
			case 1:	mode = 4; break;
			case 2:	mode = 13; break;
			case 5:	mode = 14; break;
			default:break;
			}
			UpdateListCtrlData* pData = new UpdateListCtrlData;
			
			while (LatchedFlag) {
				float pos = 0;
				int mark = 0;
				int axis = _ttoi(enocderAxis);
				PMC_Regist(Data::handle, axis, mode);

				if (mode == 3 || mode == 4)
				{
					while (mark != -1 && LatchedFlag) {
						//std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 短暂停顿
						int ret = PMC_GetMark(Data::handle, axis, &mark);
						if (!LatchedFlag) {
							return;
						}
					}
					PMC_GetRegPos(Data::handle, axis, &pos);
				}
				else
				{
					while (mark == 0 && LatchedFlag) {
						//std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 短暂停顿
						PMC_GetMarkB(Data::handle, axis, &mark);
						if (!LatchedFlag)	return;
					}
					PMC_GetRegPosB(Data::handle, axis, &pos);
				}

				pData->str.Format(_T("%d"),Num);
				pData->strPoint.Format(_T("%.2f"), pos);
				CWnd* pMainWnd = this;
				if (pMainWnd)
				{
					//发送消息到主线程
					pMainWnd->PostMessage(WM_UPDATE_LISTCTRL, reinterpret_cast<WPARAM>(pData), 0);
				}
				Num++;
			}
			}).detach();		//分离线程

	}
	else
	{
		LatchedFlag = false;
		GetDlgItem(IDC_EnocderAxis)->EnableWindow(true);
		GetDlgItem(IDC_Mode)->EnableWindow(true);
		GetDlgItem(IDC_Open)->SetWindowTextW(_T("开启"));
	}

}

/// <summary>
/// 位置比较
/// </summary>
void HwPs_Regist::OnBnClickedOpencompare()
{
	// TODO: 在此添加控件通知处理程序代码
	if (!CompareFlag)
	{
		bool open1 = ((CButton*)GetDlgItem(IDC_CHECK1))->GetCheck();	//启动比较器
		bool open2 = ((CButton*)GetDlgItem(IDC_CHECK2))->GetCheck();	//定时反转
		int m_PointsNum = m_CompareList.GetItemCount();
		if (m_PointsNum <= 0 || !open1)
		{
			GetDlgItem(IDC_OpenCompare)->SetWindowTextW(_T("开启"));
			AfxMessageBox(_T("请先增加需要比较的点位或开启比较器"));
			return;
		}		
		GetDlgItem(IDC_OpenCompare)->SetWindowTextW(_T("开启中"));		
		GetDlgItem(IDC_Add)->EnableWindow(false);				//新增
		GetDlgItem(IDC_Delect)->EnableWindow(false);			//重复次数
		GetDlgItem(IDC_CHECK1)->EnableWindow(false);			//启用比较器
		GetDlgItem(IDC_CompareAxis)->EnableWindow(false);		//比较轴号
		GetDlgItem(IDC_Out)->EnableWindow(false);				//比较输出口
		GetDlgItem(IDC_StartState)->EnableWindow(false);		//起点输出状态
		GetDlgItem(IDC_Dir)->EnableWindow(false);				//比较方向
		GetDlgItem(IDC_CHECK2)->EnableWindow(false);			//定时反转
		GetDlgItem(IDC_TimeCyc)->EnableWindow(false);			//周期时间
		GetDlgItem(IDC_TimeHave)->EnableWindow(false);			//有效时间
		GetDlgItem(IDC_DoNum)->EnableWindow(false);				//重复次数

		
		
		GetDlgItem(IDC_CompareAxis)->GetWindowTextW(m_CompareAxis);	//比较轴号
		GetDlgItem(IDC_Out)->GetWindowTextW(m_OUT);					//比较输出口
		GetDlgItem(IDC_StartState)->GetWindowTextW(m_StartState);	//起点输出状态
		int m_state = m_StartState == "关闭" ? 0 : 1;
		GetDlgItem(IDC_Dir)->GetWindowTextW(m_Dir);					//比较方向
		int m_dir;
		if (m_Dir=="不判断方向")	m_dir = -1;
		else if (m_Dir == "正方向")	m_dir = 1;
		else						m_dir = 0;
		GetDlgItem(IDC_TimeCyc)->GetWindowTextW(m_TimeCye);			//周期时间
		GetDlgItem(IDC_TimeHave)->GetWindowTextW(m_TimeHave);		//有效时间
		GetDlgItem(IDC_DoNum)->GetWindowTextW(m_DoNum);				//重复次数

		
		CompareFlag = true;
		if (open1)		//比较器
		{
			float m_Point;
			for (int i = 0; i < m_PointsNum; i++)
			{
				m_Point = _ttof(m_CompareList.GetItemText(i, 1));
				PMC_SetTable(Data::handle, i, 1, &m_Point);
			}
			PMC_HwPswitch2(Data::handle, _ttof(m_CompareAxis), 2, _ttof(m_OUT), m_state, 0, 0, 0, 0);
			PMC_HwPswitch2(Data::handle, _ttof(m_CompareAxis), 1, _ttof(m_OUT), m_state, 0, m_PointsNum-1, m_dir, 0);
			//PMC_Execute(Data::handle, "HW_PSWITCH2(2)AXIS(0)", "", 0);
			//PMC_Execute(Data::handle, "HW_PSWITCH2(1,0,1,0,3,2)AXIS(0)", "", 0);
			if (open2)		//定时反转
			{
				PMC_HwTimer(Data::handle, 0, 0, 0, 0, 0, 0);
				PMC_HwTimer(Data::handle, 2,_ttof(m_TimeCye), _ttof(m_TimeHave), _ttof(m_DoNum), _ttof(m_StartState), _ttof(m_OUT));
			}
		}
		GetDlgItem(IDC_OpenCompare)->SetWindowTextW(_T("关闭"));

	}
	else
	{
		CompareFlag = false;
		GetDlgItem(IDC_Add)->EnableWindow(true);				//新增
		GetDlgItem(IDC_Delect)->EnableWindow(true);				//重复次数
		GetDlgItem(IDC_CHECK1)->EnableWindow(true);				//启用比较器
		GetDlgItem(IDC_CompareAxis)->EnableWindow(true);		//比较轴号
		GetDlgItem(IDC_Out)->EnableWindow(true);				//比较输出口
		GetDlgItem(IDC_StartState)->EnableWindow(true);			//起点输出状态
		GetDlgItem(IDC_Dir)->EnableWindow(true);				//比较方向
		GetDlgItem(IDC_CHECK2)->EnableWindow(true);				//定时反转
		GetDlgItem(IDC_TimeCyc)->EnableWindow(true);			//周期时间
		GetDlgItem(IDC_TimeHave)->EnableWindow(true);			//有效时间
		GetDlgItem(IDC_DoNum)->EnableWindow(true);				//重复次数
		GetDlgItem(IDC_OpenCompare)->SetWindowTextW(_T("开启"));
	}
}


void HwPs_Regist::OnBnClickedStarthwps()
{
	// TODO: 在此添加控件通知处理程序代码
	if (!CompareFlag)
	{
		AfxMessageBox(_T("请先开启位置比较"));
		return;
	}
	int enable = 0;
	PMC_GetAxisEnable(Data::handle, _ttof(m_CompareAxis), &enable);
	if (enable==0)
	{
		AfxMessageBox(_T("先对使用的轴使能"));
		return;
	}
	PMC_SetAtype(Data::handle, _ttof(m_CompareAxis), 1);

	GetDlgItem(IDC_StartHwPs)->SetWindowTextW(_T("运动中"));
	((CButton*)GetDlgItem(IDC_StartHwPs))->EnableWindow(false);
	GetDlgItem(IDC_Open)->EnableWindow(false);
	GetDlgItem(IDC_OpenCompare)->EnableWindow(false);
	GetDlgItem(IDC_StartPoint)->GetWindowTextW(m_startPoint);
	GetDlgItem(IDC_EndPoint)->GetWindowTextW(m_endPoint);
	PMC_SetDpos(Data::handle, _ttof(m_CompareAxis), _ttof(m_startPoint));
	PMC_SetMpos(Data::handle, _ttof(m_CompareAxis), _ttof(m_startPoint));
	SetTimer(1, 10, NULL);		//触发定时器
	PMC_Single_MoveAbs(Data::handle, _ttof(m_CompareAxis), _ttof(m_endPoint));
	std::thread([this]() {
		int idle = 0;
		while (idle == 0) {
			PMC_GetIfIdle(Data::handle, _ttof(m_CompareAxis), &idle);
			Sleep(1);
		}
		((CButton*)GetDlgItem(IDC_StartHwPs))->EnableWindow(true);
		GetDlgItem(IDC_Open)->EnableWindow(true);
		GetDlgItem(IDC_OpenCompare)->EnableWindow(true);
		GetDlgItem(IDC_StartHwPs)->SetWindowTextW(_T("启动"));
		KillTimer(1);	
		//CompareFlag = false;
		//GetDlgItem(IDC_OpenCompare)->SetWindowTextW(_T("开启"));
		}).detach();
}


void HwPs_Regist::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	uint opValue = 0;
	PMC_GetOp(Data::handle, _ttof(m_OUT), &opValue);
	((CButton*)GetDlgItem(IDC_OUTState))->SetCheck(opValue);
	CDialogEx::OnTimer(nIDEvent);
}


void HwPs_Regist::OnBnClickedDelect()
{
	// TODO: 在此添加控件通知处理程序代码
	m_CompareList.DeleteItem(m_CompareList.GetItemCount()-1);
}
